package com.funcourse.demo.business;

import com.funcourse.demo.model.AttenderStatics;
import com.funcourse.demo.model.CompeteRoom;
import com.funcourse.demo.model.Quiz;
import com.funcourse.demo.model.UserWithScore;
import com.funcourse.demo.model.UserWithScore.Score;
import com.funcourse.demo.model.repo.AttenderStaticsRepo;
import com.funcourse.demo.model.repo.QuestionSuitRepo;
import java.util.List;
import java.util.Optional;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class StaticsService {

  private static final String USER_LOCK_KEY_PREFIX = "funcourse.statics.user.lock.";

  @Autowired
  AttenderStaticsRepo attenderStaticsRepo;

  @Autowired
  QuestionSuitRepo quizRepo;

  @Autowired
  RedisTemplate redisTemplate;

  RedisResourceLock redisResourceLock;

  public void doStatics(CompeteRoom competeRoom){
    List<UserWithScore> userWithScoreList = competeRoom.getUserWithScoreList();
    userWithScoreList.forEach(this::staticsUserScore);
    Quiz quiz = competeRoom.getQuiz();
    Optional<Quiz> byId = quizRepo.findById(quiz.getId());
    if(!byId.isPresent()){
      return;
    }
    Quiz quizInDB = byId.get();
    Integer testedCount = quizInDB.getTestedCount();
    testedCount = testedCount == null? 0:testedCount;
    quizInDB.setTestedCount(++testedCount);
    quizRepo.save(quizInDB);
  }

  private void staticsUserScore(UserWithScore userWithScore) {
    String userId = userWithScore.getId();
    redisResourceLock.tryToGetResourceLockBlocking(userId);
    AttenderStatics byUserId = attenderStaticsRepo.findByUserId(userId);
    if(null == byUserId){
      byUserId = new AttenderStatics(null,userId,0,0,0,0);
    }
    byUserId.increaseCompeteCount();
    if(userWithScore.getRanking() == 1){
      byUserId.increaseChampionCount();
    }
    for(Score s:userWithScore.getScoreDetails()){
      if(s.getScore()>0){
        byUserId.increaseRightCount();
      }else{
        byUserId.increaseWrongCount();
      }
    }
    attenderStaticsRepo.save(byUserId);
    redisResourceLock.releaseResourceLock(userId);
  }

  @PostConstruct
  public void initRedisResourceLock(){
    redisResourceLock = new RedisResourceLock(USER_LOCK_KEY_PREFIX,redisTemplate);
  }

}
